module uart_rx(//接收端模块
    input  wire       sys_clk     ,
    input  wire       sys_rst_n   ,
    input  wire       rx          ,//接收的串行数据

    output wire [7:0] rx_dout     ,//接收的8bit的数据，并行
    output reg        rx_vld//接收是否完成的标志
);

//定义波特率
parameter TIME_BAUD = 9'd434;//发送一个bit的数据需要多少个时钟周期 115200 57600 38400 19200 9600

//寄存器定义

//打拍寄存器
reg rx0;
reg rx1;
wire nedge;//开始接收数据的标志

reg add_flag;//开始接收数据的标志

reg [7:0] rx_data;//接收完成的数据
reg [8:0] rx_data_r;

//计数器定义

//波特率计数器
reg [8:0] cnt_baud;
wire add_cnt_baud;
wire end_cnt_baud;//计满一次，意味着发送完成1bit数据

//bit计数器
reg [3:0] cnt_bit;
wire add_cnt_bit;
wire end_cnt_bit;//计满一次，完成一次数据发送，10bit

always @(posedge sys_clk or negedge sys_rst_n) begin
    if(!sys_rst_n)begin//空闲状态，都为高电平
        rx0 <= 1'b1;
        rx1 <= 1'b1;
    end
    else begin
        rx0 <= rx;
        rx1 <= rx0;
    end
end

assign nedge = ~rx0  & rx1;//开始接收数据

//约束add_flag
always @(posedge sys_clk or negedge sys_rst_n) begin
    if(!sys_rst_n)begin
        add_flag <= 1'b0;
    end
    else if(nedge)begin//开始接收数据
        add_flag <= 1'b1;
    end
    else if(end_cnt_bit)begin//结束接收数据
        add_flag <= 1'b0;
    end
    else
        add_flag <= add_flag;
end

//波特率计数
always @(posedge sys_clk or negedge sys_rst_n)begin 
   if(!sys_rst_n)begin
        cnt_baud <= 9'd0;
    end 
    else if(add_cnt_baud)begin 
            if(end_cnt_baud)begin 
                cnt_baud <= 9'd0;
            end
            else begin 
                cnt_baud <= cnt_baud + 1'd1;
            end 
    end
   else  begin
       cnt_baud <= cnt_baud;
    end
end 

assign add_cnt_baud = add_flag;//开始发送数据，则波特计数开始
assign end_cnt_baud = add_cnt_baud && cnt_baud == (TIME_BAUD - 1'd1);//计满波特率，则发送完成1bit数据

//bit计数
always @(posedge sys_clk or negedge sys_rst_n)begin 
   if(!sys_rst_n)begin
        cnt_bit <= 4'd0;
    end 
    else if(add_cnt_bit)begin 
            if(end_cnt_bit)begin 
                cnt_bit <= 4'd0;
            end
            else begin 
                cnt_bit <= cnt_bit + 1'd1;
            end 
    end
   else  begin
       cnt_bit <= cnt_bit;
    end
end 

assign add_cnt_bit = end_cnt_baud;
assign end_cnt_bit = add_cnt_bit && cnt_bit == 8;

//接收数据
always @(posedge sys_clk or negedge sys_rst_n) begin
    if(!sys_rst_n)begin
        rx_data_r <= 9'd0;
    end
    else if(add_flag && (cnt_baud == (TIME_BAUD >> 1)))begin
        rx_data_r <= {rx1,rx_data_r[8:1]};
    end
    else
        rx_data_r <= rx_data_r;
end

//对接收到的数据进行处理
always @(posedge sys_clk or negedge sys_rst_n) begin
    if(!sys_rst_n)begin
        rx_data <= 8'd0;
    end
    else if(end_cnt_bit)begin
        rx_data <= rx_data_r[8:1];//截去起始符
    end
    else
        rx_data <= rx_data;
end

assign rx_dout = rx_data;

//接收空闲标志约束 rx_vld
always @(posedge sys_clk or negedge sys_rst_n)begin 
    if(!sys_rst_n)begin
        rx_vld <= 1'b0;
    end 
    else if(end_cnt_bit)begin 
        rx_vld <= 1'b1;
    end 
    else begin 
        rx_vld <= 1'b0;
    end 
end

endmodule